//
//  BARefreshControl.swift
//  BARefreshControl
//
//  Created by baggio on 2017/8/25.
//  Copyright © 2017年 baggio. All rights reserved.
//

/*
 - 自定义下拉刷新控件分析
    继承于谁 -> UIControl
    添加到谁身上 -> tableView
 - 分析控件的状态
    正常中（拖动tableView）
    下拉中（拖动tableView）
    刷新中 （当前的状态为下拉中 且松手）
 
 - 通过UIControl中 willMove(toSuperview newSuperview: UIView?) 获得父控件
 - 通过KVO完成监听父控件的属性变化
    KVO注册
    KVO实现
    deinit KVO移除
 - KVO实现找到TableView判断的临界值-114
    拖动TableView
        正常
        下拉
    停止拖动
        如果其状态为下拉 -> 刷新
 - 添加MessageLabel、箭头、菊花
 - 定义一个全局的属性type 决定MessageLabel、箭头、菊花的显示
 */

import UIKit

//因为系统 UIRefreshControl 继承 UIControl
//也可以不继承 UIControl，继承 UIView，只不过 UIView 没有 sendAction()，要使用闭包来通知
class BARefreshControl: UIControl {
    
//    var closure:(() -> ())?
    
    //控件高度
    private let BARefreshControlHeight: CGFloat = 50
    
    //一共3个状态
    enum BARefreshControlType: String {
        case normal = "正常中"
        case pulling = "下拉中"
        case refreshing = "刷新中"
    }
    
    //外界可以给 backgroundColor 赋值
    var bgColor: UIColor? = UIColor.darkGray {
        didSet{
            backgroundColor = bgColor
        }
    }
    
    
    //父控件
    private var scrollView: UIScrollView?
    
    //状态
    private var type: BARefreshControlType = .normal {
        didSet {
            //赋值，通过枚举名获得枚举值
            messageLabel.text = type.rawValue
            
            switch type {
            case .normal:
                //print("normal")
                
                //refreshing 转 normal，要结束顶部停留（缩回去）
                //oldValue 是赋值前的值
                if oldValue == .refreshing{
                    UIView.animate(withDuration: 0.5, animations: {
                        //结束顶部停留
                        self.scrollView?.contentInset.top -= self.BARefreshControlHeight
                    }, completion: { (_) in
                        //显示箭头，隐藏菊花
                        self.pullRefreshImageView.isHidden = false
                        self.indicatorView.stopAnimating()
//                        self.indicatorView.isHidden = true
                    })
                }
                //箭头恢复
                UIView.animate(withDuration: 0.5, animations: {
//                    self.pullRefreshImageView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi*2))
                    //另一种做法，恢复原状
                    self.pullRefreshImageView.transform = CGAffineTransform.identity
                }, completion: { (_) in
                })
            case .pulling:
                //print("pulling")
                
                //箭头转-180度（-是逆时针转，-540度是只在右半圈里面转）
                UIView.animate(withDuration: 0.5, animations: {
                    self.pullRefreshImageView.transform = CGAffineTransform(rotationAngle: CGFloat(-3 * Double.pi))
                }, completion: { (_) in
                })
                
            case .refreshing:
                //print("refreshing")
                
                //写到动画里
//                //顶部停留，顶部边界+BARefreshControlHeight
//                scrollView?.contentInset.top += BARefreshControlHeight
//                
//                //隐藏箭头，显示菊花
//                pullRefreshImageView.isHidden = true
//                indicatorView.isHidden = false
//                indicatorView.startAnimating()
                
                UIView.animate(withDuration: 0.3, animations: {
                    //要停留在顶部一小会，顶部边界 +BARefreshControlHeight
                    self.scrollView?.contentInset.top += self.BARefreshControlHeight
                    
                    //隐藏箭头，显示菊花
                    self.pullRefreshImageView.isHidden = true
                    //菊花不需要设置 isHidden，start 就是显示，stop 就是消失
//                    self.indicatorView.isHidden = false
                    self.indicatorView.startAnimating()
                }, completion: { (_) in
                    //刷新结束，通知外界
                    //self.sendActions(for: .valueChanged) 需要和外界的 v.addTarget(self, action: #selector(), for: .valueChanged) 对应
                    self.sendActions(for: .valueChanged)
                    
//                    self.closure!()
                })
                
     
//            //只有3种情况，不需要 default
//            default:
//                <#code#>
            }
        }
    }
    
    //结束菊花动画 
    //标准用法 refreshControl.endRefreshing()，所以 BARefreshControl 中也要有一个 endRefreshing()
    func endRefreshing() {
        type = .normal
    }
    
    //缩在导航栏上面
    override init(frame: CGRect) {
        super.init(frame: CGRect(x: 0, y: -BARefreshControlHeight, width: UIScreen.main.bounds.width, height: BARefreshControlHeight))
        
        setUpUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setUpUI() {
//        backgroundColor = UIColor.orange
        backgroundColor = bgColor
        tintColor = UIColor.blue
        
        addSubview(messageLabel)
        addSubview(pullRefreshImageView)
        addSubview(indicatorView)
        
        //系统 constraint
        //禁止Autoresizing
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        pullRefreshImageView.translatesAutoresizingMaskIntoConstraints = false
        addConstraint(NSLayoutConstraint(item: pullRefreshImageView, attribute: .centerX, relatedBy: .equal, toItem: messageLabel, attribute: .centerX, multiplier: 1, constant: -35))
        addConstraint(NSLayoutConstraint(item: pullRefreshImageView, attribute: .centerY, relatedBy: .equal, toItem: messageLabel, attribute: .centerY, multiplier: 1, constant: 0))
        
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: messageLabel, attribute: .centerX, multiplier: 1, constant: -35))
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: messageLabel, attribute: .centerY, multiplier: 1, constant: 0))
//        indicatorView.startAnimating()
    }
    
    //BARefreshControl 要监听其父控件 tableView 上下滑动时 y 坐标的变化
    //监听自己添加到哪个父控件身上
    override func willMove(toSuperview newSuperview: UIView?) {
//        print(newSuperview)
        //父控件要能滚动
        //不能写成 guard let view = newSuperview, view as? UIScrollView else {
        guard let scrollView = newSuperview as? UIScrollView else {
            return
        }
        
        //KVO 注册观察者模式
        //监听者 addObserver 和 removeObserver，被监听者 observeValue
        //scrollView.contentOffset，"contentOffset" 不能写错
        //options: [] 或 options: .new
        scrollView.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        
        self.scrollView = scrollView
    }
    
    //KVO 实现观察者模式
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        //print(scrollView?.contentOffset.y)
        //y 坐标的初始值是 -64.0
        //越往下拉，负值越大，数值越小，临界点是 -64-BARefreshControlHeight = -114
        let contentOffsetY = scrollView!.contentOffset.y //转成必选值，下面用起来方便些
        
        if scrollView!.isDragging {
            //上下滚动时
            if contentOffsetY >= (-64-BARefreshControlHeight) && (type == .pulling || type == .refreshing) {
                //“下拉中”或“刷新中”切换到“正常中”
                //print("正常中")
                type = .normal
            } else if contentOffsetY < (-64-BARefreshControlHeight) && type == .normal {
                //“正常中”切换到“下拉中”
                //print("下拉中")
                type = .pulling
            }
        } else {
            //没有滚动（即：下拉后松开）
            if type == .pulling {
                //“下拉中”切换到“刷新中”
                //print("刷新中")
                type = .refreshing
            }
        }
    }
    
    //析构函数
    deinit {
        //KVO 移除观察者
        scrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    //文字
    private var messageLabel: UILabel = {
       let label = UILabel()
        label.text = "正常中"
        label.font = UIFont.systemFont(ofSize: 14)
        label.textAlignment = .center
        label.textColor = UIColor.white
        return label
    }()
    
    //箭头
    private var pullRefreshImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    
    //菊花
    private var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView()
    
    

}
